package com.example.pm.service.impl;


import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.pm.common.constant.RedisConstant;
import com.example.pm.common.constant.SystemConstant;
import com.example.pm.common.redis.RedisUtils;
import com.example.pm.common.result.R;
import com.example.pm.common.utils.IPUtils;
import com.example.pm.common.utils.MobileUtils;
import com.example.pm.common.utils.StringUtils;
import com.example.pm.domain.Bo.LoginBo;
import com.example.pm.domain.Bo.PageBo;
import com.example.pm.domain.Login;
import com.example.pm.domain.User;
import com.example.pm.domain.Vo.PageVo;
import com.example.pm.mapper.EmployeeMapper;
import com.example.pm.mapper.LoginMapper;
import com.example.pm.mapper.UserMapper;
import com.example.pm.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mobile.device.DeviceUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private EmployeeMapper employeeMapper;


    @Override
    public R<Object> doLogin(LoginBo loginBo) {
        if (loginBo.getAccount().isEmpty()) return R.warn("账号不能为空");
        if (loginBo.getPassword().isEmpty()) return R.warn("密码不能为空");
        if (loginBo.getCode().isEmpty()) return R.warn("验证码不能为空");

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getZh, loginBo.getAccount());
        User user = userMapper.selectOne(lqw);
        if (StringUtils.isEmpty(user)) {
            return R.fail("账号不存在");
        }
        String ip = IPUtils.getIp(request);
        if (redisUtils.noHasKey(RedisConstant.code + ":" + ip))
            return R.warn("验证码已经过期");
        if (!loginBo.getCode().equals(redisUtils.get(RedisConstant.code + ":" + ip)))
            return R.warn("验证码不正确");
        if (SystemConstant.USER_STATUS_DISABLE.equals(user.getZt())) {
            return R.fail("账号已被禁用，请联系管理员解封");
        }
        int errorNum = 0;
        String key = SystemConstant.USER_STATUS_TEMPORARILY_DISABLE + ":" + user.getZh();
        if (redisUtils.hasKey(key)) {
            errorNum = (int) redisUtils.get(key);
        }
        if (errorNum >= SystemConstant.passwordErrorNum)
            return R.fail("此账号因密码错误次数太对，已经被暂时禁用。");


        String password1 = loginBo.getPassword();//用户输入的密码
        String password2 = user.getMm();//数据库中保存的密码
        String sha256 = SaSecureUtil.sha256(password1 + user.getYz());//（用户输入的密码+盐值）加密
        if (!sha256.equals(password2)) {
            long time = SystemConstant.passwordErrorNum_Time;
            redisUtils.set(key, errorNum + 1, time);
            return R.fail("密码错误");
        }
        //登录成功
        if (errorNum > 0) redisUtils.del(key);

        //添加登录记录
        Login login = new Login();
        login.setTime(LocalDateTime.now());
        login.setAccount(user.getZh());
        String innerIp = IPUtils.innerIp(ip);
        login.setInnerIp(innerIp);
        String mobile = MobileUtils.getDeviceFrom(DeviceUtils.getCurrentDevice(request));
        login.setMobile(mobile);
        login.setIp(ip);
        loginMapper.insertLogin(login);

        SaLoginModel saLoginModel = new SaLoginModel().setDevice(mobile);
        StpUtil.login(user.getZh(), saLoginModel);
        String token = StpUtil.getTokenValue();
        String tokenName = SaManager.getConfig().getTokenName();
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("tokenName", tokenName);

        return R.ok("登录成功", map);
    }

    @Override
    public PageVo<Login> getLoginList(PageBo pageBo) {
        LambdaQueryWrapper<Login> lqw = new LambdaQueryWrapper<>();
        lqw.orderBy(true, false, Login::getTime);
        List<Login> logins = loginMapper.selectList(lqw);
        return new PageVo<>(pageBo, logins);
    }

    @Override
    public R<PageVo<Login>> getLoginListBySearch(Login login, PageBo pageBo) {
        LambdaQueryWrapper<Login> lqw = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(login.getAccount()))
            lqw.eq(Login::getAccount, login.getAccount());
        if (StringUtils.isNotEmpty(login.getXm()))
            lqw.like(Login::getXm, login.getXm());
        lqw.orderByDesc(Login::getTime);
        List<Login> logins = loginMapper.selectList(lqw);
        if (StringUtils.isEmpty(logins)) return R.ok("没有符合条件的数据", new PageVo<>());
        return R.ok(new PageVo<>(pageBo, logins));
    }

    @Override
    public List<Login> getListIndex() {
        String account = (String) StpUtil.getLoginId();
        LambdaQueryWrapper<Login> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Login::getAccount, account);
        lqw.orderBy(true, false, Login::getTime);
        lqw.last("LIMIT 5");
        return loginMapper.selectList(lqw);
    }

}
